using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Net;
using System.IO;

namespace Ares.Walker
{
    public class PostWalker : WalkerBase
    {
        private Thread th;
        private bool ffinished;
        private string FAddress;
        private string[] FList;
        private int FCount;
        private int FMinutes;
        private int FSeconds;
        private bool FTerminated;
        private int FTimeOut;
        private byte[] FPostData;

        public string Address
        {
            get
            {
                return this.FAddress;
            }
        }
        
        public bool Finished
        {
            get
            {
                return this.ffinished;
            }
        }

        public string[] List
        {
            get
            {
                return FList;
            }
        }

        public int Count
        {
            get
            {
                return FCount;
            }
        }
        

        public PostWalker(string Address, string[] List, int Count, int Minutes, int Seconds, int Timeout, string PostData)
        {
            this.FTerminated = false;
            this.ffinished = false;
            this.FAddress = Address;
            this.FList = List;
            this.FCount = Count;
            this.FMinutes = Minutes;
            this.FSeconds = Seconds;
            this.FTimeOut = Timeout*1000;

            this.FPostData = Encoding.ASCII.GetBytes(PostData);
            this.th=new Thread(this.ThreadFunc);            
        }

        public override void Start()
        {
            this.th.Start();
        }

        public override void Terminate()
        {
            FTerminated = true;
            th.Abort();
        }        

        private void ThreadFunc()
        {
            Uri url = new Uri(this.FAddress);            
            int i = 0;
            while (true)
            {
                if (FTerminated)
                    break;
                try
                {
                    HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);                                        
                    req.Proxy = new WebProxy(FList[i % FList.Length]);
                    i++;  //i must be incremented
                    req.Timeout = this.FTimeOut;
                    req.Method = "POST";
                    req.ContentType = "application/x-www-form-urlencoded";
                    req.ContentLength = this.FPostData.Length;
                    DoSending(i, ((WebProxy)req.Proxy).Address.ToString());
                    Stream st = req.GetRequestStream();
                    st.Write(this.FPostData, 0, this.FPostData.Length);
                    st.Close();                                        
                    
                    WebResponse resp = req.GetResponse();
                    DoSent(i, ((WebProxy)req.Proxy).Address.ToString());

                    long time = Environment.TickCount + Convert.ToInt32(((new TimeSpan(0, FMinutes, FSeconds)).TotalMilliseconds));
                    while (time > Environment.TickCount)
                    {
                        TimeSpan diff = TimeSpan.FromMilliseconds(time - Environment.TickCount);
                    
                        DoWait(diff.Minutes, diff.Seconds);
                        
                        if (FTerminated)
                        {                            
                            break;
                        }
                        Thread.Sleep(100);
                    }                    
                } 
                catch (ThreadAbortException)
                {                 
                    ffinished = true;
                    break;
                }
                catch (Exception e)
                {
                    DoError(e);  
                }

                if (FTerminated)
                {                    
                    break;
                }

                if (i == FCount)
                    break;
            }

            this.ffinished = true;
        }
    }
}
